home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / srcuc.zip / DOSIO.C < prev    next >
C/C++ Source or Header  |  1992-05-05  |  12KB  |  499 lines

  1. /* -*-C-*-
  2.  
  3. $Header: /scheme/dos386/microcode/RCS/dosio.c,v 1.1 1992/05/05 06:55:13 jinx Exp $
  4.  
  5. Copyright (c) 1992 Massachusetts Institute of Technology
  6.  
  7. This material was developed by the Scheme project at the Massachusetts
  8. Institute of Technology, Department of Electrical Engineering and
  9. Computer Science.  Permission to copy this software, to redistribute
  10. it, and to use it for any purpose is granted, subject to the following
  11. restrictions and understandings.
  12.  
  13. 1. Any copy made of this software must include this copyright notice
  14. in full.
  15.  
  16. 2. Users of this software agree to make their best efforts (a) to
  17. return to the MIT Scheme project any improvements or extensions that
  18. they make, so that these may be included in future releases; and (b)
  19. to inform MIT of noteworthy uses of this software.
  20.  
  21. 3. All materials developed as a consequence of the use of this
  22. software shall duly acknowledge such use, in accordance with the usual
  23. standards of acknowledging credit in academic research.
  24.  
  25. 4. MIT has made no warrantee or representation that the operation of
  26. this software will be error-free, and MIT is under no obligation to
  27. provide any services, by way of maintenance, update, or otherwise.
  28.  
  29. 5. In conjunction with products arising from the use of this material,
  30. there shall be no use of the name of the Massachusetts Institute of
  31. Technology nor of any adaptation thereof in any advertising,
  32. promotional, or sales literature without prior written consent from
  33. MIT in each case. */
  34.  
  35. #include "msdos.h"
  36. #include "dosio.h"
  37. #include "osterm.h"
  38.  
  39. #ifdef __STDC__
  40. #define fileno(fp)    ((fp)->_file)
  41. #endif
  42.  
  43. size_t OS_channel_table_size;
  44. struct channel * channel_table;
  45.  
  46. unsigned int OS_channels_registered;
  47.  
  48. static void
  49. DEFUN_VOID (DOS_channel_close_all)
  50. {
  51.   Tchannel channel;
  52.   for (channel = 0; (channel < OS_channel_table_size); channel += 1)
  53.     if (CHANNEL_OPEN_P (channel))
  54.       OS_channel_close_noerror (channel);
  55. }
  56.  
  57. void
  58. DEFUN_VOID (DOS_initialize_channels)
  59. {
  60.   OS_channel_table_size = (DOS_SC_OPEN_MAX ());
  61.   channel_table =
  62.     (DOS_malloc (OS_channel_table_size * (sizeof (struct channel))));
  63.   if (channel_table == 0)
  64.     {
  65.       fprintf (stderr, "\nUnable to allocate channel table.\n");
  66.       fflush (stderr);
  67.       termination_init_error ();
  68.     }
  69.   {
  70.     Tchannel channel;
  71.     for (channel = 0; (channel < OS_channel_table_size); channel += 1)
  72.       MARK_CHANNEL_CLOSED (channel);
  73.   }
  74.   add_reload_cleanup (DOS_channel_close_all);
  75.   OS_channels_registered = 0;
  76. }
  77.  
  78. void
  79. DEFUN_VOID (DOS_reset_channels)
  80. {
  81.   DOS_free (channel_table);
  82.   channel_table = 0;
  83.   OS_channel_table_size = 0;
  84. }
  85.  
  86. Tchannel
  87. DEFUN_VOID (channel_allocate)
  88. {
  89.   Tchannel channel = 0;
  90.   while (1)
  91.     {
  92.       if (channel == OS_channel_table_size)
  93.     error_out_of_channels ();
  94.       if (CHANNEL_CLOSED_P (channel))
  95.     return (channel);
  96.       channel += 1;
  97.     }
  98. }
  99.  
  100. int
  101. DEFUN (OS_channel_open_p, (channel), Tchannel channel)
  102. {
  103.   return (CHANNEL_OPEN_P (channel));
  104. }
  105.  
  106. void
  107. DEFUN (OS_channel_close, (channel), Tchannel channel)
  108. {
  109.   if (! (CHANNEL_INTERNAL (channel)))
  110.     {
  111.       if (CHANNEL_REGISTERED (channel))
  112.     OS_channel_unregister (channel);
  113.       STD_VOID_SYSTEM_CALL
  114.     (syscall_close, (DOS_close (CHANNEL_DESCRIPTOR (channel))));
  115.       MARK_CHANNEL_CLOSED (channel);
  116.     }
  117. }
  118.  
  119. void
  120. DEFUN (OS_channel_close_noerror, (channel), Tchannel channel)
  121. {
  122.   if (! (CHANNEL_INTERNAL (channel)))
  123.     {
  124.       if (CHANNEL_REGISTERED (channel))
  125.     OS_channel_unregister (channel);
  126.       DOS_close (CHANNEL_DESCRIPTOR (channel));
  127.       MARK_CHANNEL_CLOSED (channel);
  128.     }
  129. }
  130.  
  131. static void
  132. DEFUN (channel_close_on_abort_1, (cp), PTR cp)
  133. {
  134.   OS_channel_close (* ((Tchannel *) cp));
  135. }
  136.  
  137. void
  138. DEFUN (OS_channel_close_on_abort, (channel), Tchannel channel)
  139. {
  140.   Tchannel * cp = (dstack_alloc (sizeof (Tchannel)));
  141.   (*cp) = (channel);
  142.   transaction_record_action (tat_abort, channel_close_on_abort_1, cp);
  143. }
  144.  
  145. enum channel_type
  146. DEFUN (OS_channel_type, (channel), Tchannel channel)
  147. {
  148.   return (CHANNEL_TYPE (channel));
  149. }
  150.  
  151. void
  152. DEFUN (OS_terminal_flush_input, (channel), Tchannel channel)
  153. { extern void EXFUN (flush_conio_buffers, (void));
  154.  
  155.   if ((CHANNEL_DESCRIPTOR (channel)) == (fileno (stdin)))
  156.     flush_conio_buffers();
  157.   return;
  158. }
  159.  
  160. void
  161. DEFUN (OS_terminal_flush_output, (channel), Tchannel channel)
  162. {
  163.   return;
  164. }
  165.  
  166. void
  167. DEFUN (OS_terminal_drain_output, (channel), Tchannel channel)
  168. {
  169.   return;
  170. }
  171.  
  172. DEFUN (dos_channel_read, (channel, buffer, nbytes),
  173.        Tchannel channel AND PTR buffer AND size_t nbytes)
  174. {
  175.   if (nbytes == 0)
  176.     return 0;
  177.   else if (CHANNEL_DESCRIPTOR (channel) == fileno(stdin))
  178.     return console_read(buffer, nbytes, 
  179.             CHANNEL_BUFFERED(channel), CHANNEL_BLOCKING_P(channel));
  180.   else
  181.     return DOS_read ((CHANNEL_DESCRIPTOR (channel)), buffer, nbytes);
  182. }
  183.  
  184. long
  185. DEFUN (OS_channel_read, (channel, buffer, nbytes),
  186.        Tchannel channel AND PTR buffer AND size_t nbytes)
  187. {
  188.   while (1)
  189.   {
  190.     long scr = dos_channel_read(channel, buffer, nbytes);    
  191.     if (scr < 0)
  192.     {
  193.       if (errno == ERRNO_NONBLOCK)
  194.     return -1;
  195.       DOS_prim_check_errno (syscall_read);
  196.       continue;
  197.     }
  198.     else if (scr > nbytes)
  199.       error_external_return ();
  200.     else
  201.       return (scr);
  202.   }
  203. }
  204.  
  205. static int
  206. DEFUN (dos_write, (fd, buffer, nbytes),
  207.        int fd AND CONST unsigned char * buffer AND size_t nbytes)
  208. {
  209.   return ( (fd == fileno(stdout))
  210.        ? dos_console_write(buffer, nbytes)
  211.        : write(fd, buffer, nbytes) );
  212. }
  213.  
  214. #define Syscall_Write(fd, buffer, size, so_far)        \
  215. do                            \
  216. { size_t _size = (size);                \
  217.   int _written;                        \
  218.   _written = dos_write((fd), (buffer), (_size));    \
  219.   if (_size != _written)                \
  220.     return ((_written < 0) ? -1 : (so_far) + _written); \
  221. } while (0)
  222.  
  223. long
  224. DEFUN (text_write, (fd, buffer, nbytes),
  225.        int fd AND CONST unsigned char * buffer AND size_t nbytes)
  226. { /* Map LF to CR/LF */
  227.   static CONST unsigned char crlf[] = {CARRIAGE_RETURN, LINEFEED};
  228.   CONST unsigned char *start;
  229.   size_t i;
  230.  
  231.   for (i=0, start=buffer; i < nbytes; start = &buffer[i])
  232.   { size_t len;
  233.  
  234.     while ((i < nbytes)&&(buffer[i] != LINEFEED)) i++;
  235.     len = (&buffer[i] - start);
  236.  
  237.     Syscall_Write(fd, start, len, (i - len));
  238.  
  239.     if ((i < nbytes)&&(buffer[i] == LINEFEED))
  240.     { /* We are sitting on a linefeed. Write out CRLF */
  241.       /* This backs out incorrectly if only CR is written out */
  242.       Syscall_Write(fd, crlf, sizeof(crlf), i);
  243.       i = i + 1; /* Skip over special character */
  244.     }
  245.   }
  246.  
  247.   return nbytes;
  248. }
  249.  
  250. #undef Syscall_Write
  251.  
  252. long
  253. DEFUN (OS_channel_write, (channel, buffer, nbytes),
  254.        Tchannel channel AND CONST PTR buffer AND size_t nbytes)
  255. {
  256.   if (nbytes == 0) return (0);
  257.  
  258.   while (1)
  259.   { int fd, scr;
  260.  
  261.     fd = CHANNEL_DESCRIPTOR(channel);
  262.     scr = ((CHANNEL_COOKED(channel))
  263.        ? text_write(fd, buffer, nbytes)
  264.        : dos_write(fd, buffer, nbytes));
  265.           
  266.     if (scr < 0)
  267.     {
  268.       DOS_prim_check_errno (syscall_write);
  269.       continue;
  270.     }
  271.  
  272.     if (scr > nbytes)
  273.       error_external_return ();
  274.     return scr;
  275.   }
  276. }
  277.  
  278.  
  279. size_t
  280. DEFUN (OS_channel_read_load_file, (channel, buffer, nbytes),
  281.        Tchannel channel AND PTR buffer AND size_t nbytes)
  282. {
  283.   int scr;
  284.   scr = (DOS_read ((CHANNEL_DESCRIPTOR (channel)), buffer, nbytes));
  285.   return ((scr < 0) ? 0 : scr);
  286. }
  287.  
  288. size_t
  289. DEFUN (OS_channel_write_dump_file, (channel, buffer, nbytes),
  290.        Tchannel channel AND CONST PTR buffer AND size_t nbytes)
  291. {
  292.   int scr = (DOS_write ((CHANNEL_DESCRIPTOR (channel)), buffer, nbytes));
  293.   return ((scr < 0) ? 0 : scr);
  294. }
  295.  
  296. void
  297. DEFUN (OS_channel_write_string, (channel, string),
  298.        Tchannel channel AND
  299.        CONST char * string)
  300. {
  301.   unsigned long length = (strlen (string));
  302.   if ((OS_channel_write (channel, string, length)) != length)
  303.     error_external_return ();
  304. }
  305.  
  306. void
  307. DEFUN (OS_make_pipe, (readerp, writerp),
  308.        Tchannel * readerp AND
  309.        Tchannel * writerp)
  310. {
  311.   return;
  312. }
  313.  
  314. int
  315. DEFUN (OS_channel_nonblocking_p, (channel), Tchannel channel)
  316. {
  317.   return (CHANNEL_NONBLOCKING (channel));
  318. }
  319.  
  320. void
  321. DEFUN (OS_channel_nonblocking, (channel), Tchannel channel)
  322. {
  323.   (CHANNEL_NONBLOCKING (channel)) = 1;
  324.   return;
  325. }
  326.  
  327. void
  328. DEFUN (OS_channel_blocking, (channel), Tchannel channel)
  329. {
  330.   (CHANNEL_NONBLOCKING (channel)) = 0;
  331. }
  332.  
  333. int
  334. DEFUN (OS_terminal_buffered_p, (channel), Tchannel channel)
  335. {
  336.   return (CHANNEL_BUFFERED(channel));
  337. }
  338.  
  339. void
  340. DEFUN (OS_terminal_buffered, (channel), Tchannel channel)
  341. {
  342.   CHANNEL_BUFFERED(channel) = 1;
  343. }
  344.  
  345. void
  346. DEFUN (OS_terminal_nonbuffered, (channel), Tchannel channel)
  347. {
  348.   CHANNEL_BUFFERED(channel) = 0;
  349. }
  350.  
  351. int
  352. DEFUN (OS_terminal_cooked_output_p, (channel), Tchannel channel)
  353. {
  354.   return (CHANNEL_COOKED(channel));
  355. }
  356.  
  357. void
  358. DEFUN (OS_terminal_cooked_output, (channel), Tchannel channel)
  359. {
  360.   CHANNEL_COOKED(channel) = 1;
  361. }
  362.  
  363. void
  364. DEFUN (OS_terminal_raw_output, (channel), Tchannel channel)
  365. {
  366.   CHANNEL_COOKED(channel) = 0;
  367. }
  368.  
  369. unsigned int
  370. DEFUN (arg_baud_index, (argument), unsigned int argument)
  371. {
  372.   return (arg_index_integer (argument, 1));
  373. }
  374.  
  375. unsigned long
  376. DEFUN (OS_terminal_get_ispeed, (channel), Tchannel channel)
  377. {
  378.   return (0);
  379. }
  380.  
  381. unsigned long
  382. DEFUN (OS_terminal_get_ospeed, (channel), Tchannel channel)
  383. {
  384.   return (0);
  385. }
  386.  
  387. unsigned int
  388. DEFUN (OS_baud_index_to_rate, (index), unsigned int index)
  389. {
  390.   return (9600);
  391. }
  392.  
  393. int
  394. DEFUN (OS_baud_rate_to_index, (rate), unsigned int rate)
  395. {
  396.   return ((rate == 9600) ? 0 : -1);
  397. }
  398.  
  399. unsigned int
  400. DEFUN_VOID (OS_terminal_state_size)
  401. {
  402.   return (3);
  403. }
  404.  
  405. void
  406. DEFUN (OS_terminal_get_state, (channel, state_ptr),
  407.        Tchannel channel AND PTR state_ptr)
  408. {
  409.   unsigned char *statep = (unsigned char *) state_ptr;
  410.  
  411.   *statep++ = CHANNEL_NONBLOCKING(channel);
  412.   *statep++ = CHANNEL_BUFFERED(channel);
  413.   *statep   = CHANNEL_COOKED(channel);
  414.   
  415.   return;
  416. }
  417.  
  418. void
  419. DEFUN (OS_terminal_set_state, (channel, state_ptr),
  420.        Tchannel channel AND PTR state_ptr)
  421. {
  422.   unsigned char *statep = (unsigned char *) state_ptr;
  423.  
  424.   CHANNEL_NONBLOCKING(channel) = *statep++;
  425.   CHANNEL_BUFFERED(channel)    = *statep++;
  426.   CHANNEL_COOKED(channel)      = *statep;
  427.   
  428.   return;
  429. }
  430.  
  431. #ifndef FALSE
  432. #  define FALSE 0
  433. #endif
  434.  
  435. int
  436. DEFUN_VOID (OS_job_control_p)
  437. {
  438.   return (FALSE);
  439. }
  440.  
  441. int
  442. DEFUN_VOID (OS_have_ptys_p)
  443. {
  444.   return (FALSE);
  445. }
  446.  
  447. int
  448. DEFUN (OS_channel_registered_p, (channel), Tchannel channel)
  449. {
  450.   return (CHANNEL_REGISTERED (channel));
  451. }
  452.  
  453. void
  454. DEFUN (OS_channel_register, (channel), Tchannel channel)
  455. {
  456.   error_unimplemented_primitive ();
  457. }
  458.  
  459. void
  460. DEFUN (OS_channel_unregister, (channel), Tchannel channel)
  461. {
  462.   if (CHANNEL_REGISTERED (channel))
  463.     {
  464.       OS_channels_registered -= 1;
  465.       (CHANNEL_REGISTERED (channel)) = 0;
  466.     }
  467. }
  468.  
  469.  
  470. /* No SELECT in DOS */
  471. long
  472. DEFUN (OS_channel_select_then_read, (channel, buffer, nbytes),
  473.        Tchannel channel AND
  474.        PTR buffer AND
  475.        size_t nbytes)
  476. { /* We can't really select amonst channels in DOS, but still need
  477.      to keep track of whether the read was interrupted. */
  478.   while (1)
  479.   {
  480.     long scr = dos_channel_read(channel, buffer, nbytes);
  481.  
  482.     if (scr < 0)
  483.     {
  484.       if (errno == ERRNO_NONBLOCK)
  485.     return -1;
  486.       else if (errno == EINTR)
  487.     return -4;
  488.       else
  489.       { DOS_prim_check_errno (syscall_read);
  490.     continue;
  491.       }
  492.     }
  493.     else if (scr > nbytes)
  494.       error_external_return ();
  495.     else
  496.       return (scr);
  497.   }
  498. }
  499.